home *** CD-ROM | disk | FTP | other *** search
/ Oh!X 2001 Spring / Oh!X 2001 Spring Special CD-ROM (Japan).7z / Oh!X 2001 Spring Special CD-ROM (Japan) (Track 1).bin / VC / layered3 / layered3.cpp < prev    next >
C/C++ Source or Header  |  2000-08-11  |  9KB  |  293 lines

  1. // layered3.cpp : アプリケーション用のエントリ ポイントの定義
  2. //
  3.  
  4. #include "stdafx.h"
  5. #include "layeredwnd.h"
  6.  
  7. #define APPNAME "LayeredWindow3"
  8. static char szAppName[] = APPNAME;
  9. static char szTitle[]   = APPNAME;
  10.  
  11. #define MM_QUIT WM_USER+1
  12.  
  13. LayeredWnd *playeredWnd;
  14.  
  15. HINSTANCE    hInst;    // USER32.DLL のインスタンスハンドル
  16. // SetLayeredWindowAttributes のアドレス
  17. BOOL (WINAPI *_SetLayeredWindowAttributes)(HWND,COLORREF,BYTE,DWORD);
  18. // UpdateLayeredWindow のアドレス
  19. BOOL (WINAPI *_UpdateLayeredWindow)(HWND,HDC,POINT*,SIZE*,HDC,POINT*,COLORREF,BLENDFUNCTION*,DWORD);
  20.  
  21. int APIENTRY WinMain(HINSTANCE hInstance,
  22.                      HINSTANCE hPrevInstance,
  23.                      LPSTR     lpCmdLine,
  24.                      int       nCmdShow )
  25. {
  26.      // TODO: この位置にコードを記述してください。
  27.     OSVERSIONINFO versioninfo;
  28.     versioninfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
  29.     GetVersionEx( &versioninfo );
  30.     if( versioninfo.dwMajorVersion<5 ){
  31.         MessageBox( NULL, "このバージョンのWindowsでは動作しません。", "LayeredWindow",MB_OK|MB_ICONHAND ); 
  32.         return FALSE;
  33.     }
  34.     if( !InitInstance( hInstance ) ){
  35.         MessageBox( NULL, "アプリケーションの初期化に失敗しました。", "LayeredWindow", MB_OK|MB_ICONHAND );
  36.         return FALSE;
  37.     }
  38.  
  39.     MSG msg;
  40.     while( GetMessage( &msg, NULL, 0, 0 ) ){
  41.         TranslateMessage( &msg );    // Translates virtual key codes.
  42.         DispatchMessage( &msg );    // Dispatches message to window.
  43.     }
  44.     ExitInstance();
  45.     return msg.wParam;    // Returns the value from PostQuitMessage.
  46. }
  47.  
  48. BOOL InitInstance( HINSTANCE hInstance )
  49. {
  50.     // SetLayeredWindowAttributes のエクスポートアドレスの取得
  51.     hInst = LoadLibrary( "USER32.DLL" );
  52.     if( hInst ){
  53.         _SetLayeredWindowAttributes = (BOOL(WINAPI*)(HWND,COLORREF,BYTE,DWORD))
  54.             GetProcAddress( hInst, "SetLayeredWindowAttributes" );
  55.         _UpdateLayeredWindow = (BOOL(WINAPI*)(HWND,HDC,POINT*,SIZE*,HDC,POINT*,COLORREF,BLENDFUNCTION*,DWORD))
  56.             GetProcAddress( hInst, "UpdateLayeredWindow" );
  57.     }
  58.     if( _SetLayeredWindowAttributes==NULL || _UpdateLayeredWindow==NULL ) return FALSE;
  59.  
  60.     playeredWnd = new LayeredWnd( hInstance );
  61.     HWND hWnd = playeredWnd->Create();
  62.     return hWnd?TRUE:FALSE;
  63. }
  64.  
  65. void ExitInstance()
  66. {
  67.     if( playeredWnd ) delete playeredWnd;
  68.     if( hInst ) FreeLibrary( hInst );
  69. }
  70.  
  71. LONG APIENTRY MainWndProc( HWND hWnd, UINT message, UINT wParam, LONG lParam )
  72. {
  73.     if( message==WM_NCCREATE ){
  74.         CREATESTRUCT *pcs = (CREATESTRUCT*)lParam;
  75.         SetWindowLong( hWnd, GWL_USERDATA, (LONG)pcs->lpCreateParams );
  76.     }
  77.     LayeredWnd *pWnd = (LayeredWnd*)GetWindowLong( hWnd, GWL_USERDATA );
  78.     if( pWnd==NULL ){
  79.         return DefWindowProc( hWnd, message, wParam, lParam );
  80.     } else {
  81.         return pWnd->WndProc( hWnd, message, wParam, lParam );
  82.     }
  83.     return 0;
  84. }
  85.  
  86. //////////////////////////////////////////////////////////////////////
  87. // LayeredWnd クラス
  88. //////////////////////////////////////////////////////////////////////
  89.  
  90. //////////////////////////////////////////////////////////////////////
  91. // 構築/消滅
  92. //////////////////////////////////////////////////////////////////////
  93.  
  94. LayeredWnd::LayeredWnd( HINSTANCE hInstance )
  95. {
  96.     WNDCLASSEX wc;
  97.     wc.cbSize = sizeof( WNDCLASSEX );
  98.     wc.style = 0;
  99.     wc.lpfnWndProc = (WNDPROC)MainWndProc;
  100.     wc.cbClsExtra = 0;
  101.     wc.cbWndExtra = 0;
  102.     wc.hInstance = hInstance;
  103.     wc.hIcon = LoadIcon( NULL, IDI_APPLICATION );
  104.     wc.hCursor = LoadCursor( NULL, IDC_ARROW );
  105.     wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
  106.     wc.lpszMenuName = NULL;
  107.     wc.lpszClassName = szAppName;
  108.     wc.hIconSm = NULL;
  109.     RegisterClassEx( &wc );
  110.     m_hInstance = hInstance;
  111.  
  112.     m_hMenu = CreatePopupMenu();
  113.     MENUITEMINFO mi;
  114.     mi.cbSize = sizeof(MENUITEMINFO);
  115.     mi.fMask = MIIM_ID|MIIM_TYPE;
  116.     mi.fType = MFT_STRING;
  117.     mi.wID = MM_QUIT;
  118.     mi.dwTypeData = "終了";
  119.     mi.cch = strlen( mi.dwTypeData );
  120.     InsertMenuItem( m_hMenu, 0, TRUE, &mi );
  121.  
  122.     HBITMAP hBitmap = LoadBitmap( m_hInstance, MAKEINTRESOURCE(IDB_RGB) );
  123.     HBITMAP hAlpha = LoadBitmap( m_hInstance, MAKEINTRESOURCE(IDB_ALPHA) );
  124.     m_hBitmap = CreateAlphaContainedBitmap( hBitmap, hAlpha );
  125.     HDC hDC = GetDC( NULL );
  126.     m_hDC = CreateCompatibleDC( hDC );
  127.     ReleaseDC( NULL, hDC );
  128.     SelectObject( m_hDC, m_hBitmap );
  129.     m_nWidth = 200;
  130.     m_nHeight = 90;
  131.     m_nFrame = 0;
  132. }
  133.  
  134. // Alpha付きのビットマップを作成
  135. // 入力    hBitmap    カラービットマップ
  136. //        hAlpha    アルファビットマップ(R成分)
  137. // 出力    32ビットビットマップ
  138. HBITMAP LayeredWnd::CreateAlphaContainedBitmap( HBITMAP hBitmap, HBITMAP hAlpha )
  139. {
  140.     BITMAPINFOHEADER *pbmih1 = (BITMAPINFOHEADER*)GlobalAlloc( GPTR, sizeof(BITMAPINFOHEADER) );
  141.     memset( pbmih1, 0, sizeof(BITMAPINFOHEADER) );
  142.     pbmih1->biSize = sizeof(BITMAPINFOHEADER);
  143.     HDC hDC = GetDC( NULL );
  144.     GetDIBits( hDC, hBitmap, 0, 0, NULL, (BITMAPINFO*)pbmih1, DIB_RGB_COLORS );
  145.     pbmih1->biBitCount = 24;
  146.     pbmih1->biCompression = BI_RGB;
  147.     pbmih1->biXPelsPerMeter = pbmih1->biYPelsPerMeter = 0;
  148.     pbmih1->biClrUsed = pbmih1->biClrImportant = 0;
  149.  
  150.     BITMAPINFOHEADER *pbmih2 = (BITMAPINFOHEADER*)GlobalAlloc( GPTR, sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)*256 );
  151.     memset( pbmih2, 0, sizeof(BITMAPINFOHEADER) );
  152.     pbmih2->biSize = sizeof(BITMAPINFOHEADER);
  153.     GetDIBits( hDC, hAlpha, 0, 0, NULL, (BITMAPINFO*)pbmih2, DIB_RGB_COLORS );
  154.     pbmih2->biBitCount = 8;
  155.     pbmih2->biCompression = BI_RGB;
  156.     pbmih2->biXPelsPerMeter = pbmih2->biYPelsPerMeter = 0;
  157.     pbmih2->biClrUsed = pbmih2->biClrImportant = 256;
  158.     RGBQUAD *rgb = (RGBQUAD*)(pbmih2+1);
  159.  
  160.     BITMAPINFOHEADER *pbmih3 = (BITMAPINFOHEADER*)GlobalAlloc( GPTR, sizeof(BITMAPINFOHEADER) );
  161.     memset( pbmih3, 0, sizeof(BITMAPINFOHEADER) );
  162.     pbmih3->biSize = sizeof(BITMAPINFOHEADER);
  163.     pbmih3->biWidth = pbmih1->biWidth;
  164.     pbmih3->biHeight = pbmih1->biHeight;
  165.     pbmih3->biPlanes = 1;
  166.      pbmih3->biBitCount = 32;
  167.     pbmih3->biCompression = BI_RGB;
  168.     pbmih3->biSizeImage = 0;
  169.     pbmih3->biXPelsPerMeter = 0;
  170.     pbmih3->biYPelsPerMeter = 0;
  171.     pbmih3->biClrUsed = 0;
  172.     pbmih3->biClrImportant = 0;
  173.  
  174.     int line1 = (pbmih1->biWidth*3+3)/4*4;
  175.     LPBYTE lpvBits1 = (LPBYTE)GlobalAlloc( GPTR, line1*pbmih1->biHeight );
  176.     GetDIBits( hDC, hBitmap, 0, pbmih1->biHeight, lpvBits1, (BITMAPINFO*)pbmih1, DIB_RGB_COLORS );
  177.     int line2 = (pbmih2->biWidth+3)/4*4;
  178.     LPBYTE lpvBits2 = (LPBYTE)GlobalAlloc( GPTR, line2*pbmih2->biHeight );
  179.     GetDIBits( hDC, hAlpha, 0, pbmih2->biHeight, lpvBits2, (BITMAPINFO*)pbmih2, DIB_RGB_COLORS );
  180.  
  181.     LPBYTE pvBits;
  182.     HBITMAP hNewBitmap = CreateDIBSection( hDC, (BITMAPINFO*)pbmih3, DIB_RGB_COLORS, (void**)&pvBits, NULL, 0 );
  183.     LPBYTE p1 = lpvBits1, p2 = lpvBits2, p3 = pvBits;
  184.     for( int y=0; y<pbmih3->biHeight; y++ ){
  185.         for( int x=0; x<pbmih3->biWidth; x++ ){
  186.             *(p3++) = *(p1++);
  187.             *(p3++) = *(p1++);
  188.             *(p3++) = *(p1++);
  189.             *(p3++) = rgb[*(p2++)].rgbRed;
  190.         }
  191.         p1 += line1-pbmih3->biWidth*3;
  192.         p2 += line2-pbmih3->biWidth;
  193.     }
  194.     ReleaseDC( NULL, hDC );
  195.  
  196.     GlobalFree( lpvBits1 );
  197.     GlobalFree( lpvBits2 );
  198.     GlobalFree( pbmih1 );
  199.     GlobalFree( pbmih2 );
  200.     GlobalFree( pbmih3 );
  201.     return hNewBitmap;
  202. }
  203.  
  204. LayeredWnd::~LayeredWnd()
  205. {
  206.     DeleteDC( m_hDC );
  207.     DeleteObject( m_hBitmap );
  208.     DestroyMenu( m_hMenu );
  209. }
  210.  
  211. HWND LayeredWnd::Create()
  212. {
  213.     CREATESTRUCT cs;
  214.     cs.lpCreateParams = this;
  215.     cs.hInstance = m_hInstance;
  216.     cs.hMenu = NULL;
  217.     cs.hwndParent = NULL;
  218.     cs.cy = m_nHeight;
  219.     cs.cx = m_nWidth;
  220.     cs.y = CW_USEDEFAULT;
  221.     cs.x = CW_USEDEFAULT;
  222.     cs.style = WS_POPUP|WS_VISIBLE;
  223.     cs.lpszName = szTitle;
  224.     cs.lpszClass = szAppName;
  225.     cs.dwExStyle = WS_EX_LAYERED;    // レイヤードウィンドウ
  226.     m_hWnd = CreateWindowEx( cs.dwExStyle, cs.lpszClass, cs.lpszName, cs.style,
  227.         cs.x, cs.y, cs.cx, cs.cy, cs.hwndParent, cs.hMenu, cs.hInstance, cs.lpCreateParams );
  228.     return m_hWnd;
  229. }
  230.  
  231. LRESULT LayeredWnd::WndProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam )
  232. {
  233.     switch( message ){
  234.     case WM_CREATE:
  235.         OnCreate( hWnd );
  236.         return 0;
  237.     case WM_DESTROY:
  238.         OnDestroy( hWnd );
  239.         PostQuitMessage( 0 );
  240.         return 0;
  241.     case WM_NCHITTEST:
  242.         return OnNcHitTest( LOWORD(lParam), HIWORD(lParam) );
  243.     case WM_NCRBUTTONDOWN:
  244.         OnNcRButtonDown( wParam, MAKEPOINTS(lParam) );
  245.         return 0;
  246.     case WM_COMMAND:
  247.         switch( LOWORD(wParam) ){
  248.         case MM_QUIT:
  249.             DestroyWindow( m_hWnd );
  250.             return 0;
  251.         }
  252.         break;
  253.     case WM_TIMER:
  254.         m_nFrame = Animate( hWnd, m_nFrame );
  255.         return 0;
  256.     }
  257.     return DefWindowProc( hWnd, message, wParam, lParam );
  258. }
  259.  
  260. void LayeredWnd::OnCreate( HWND hWnd )
  261. {
  262.     m_nFrame = Animate( hWnd, m_nFrame );
  263.     SetTimer( hWnd, 1, 100, NULL );
  264. }
  265.  
  266. int LayeredWnd::Animate( HWND hWnd, int frm )
  267. {
  268.     POINT point = { (frm%5)*m_nWidth, (frm/5)*m_nHeight };
  269.     SIZE size = { m_nWidth, m_nHeight };
  270.     BLENDFUNCTION blend;
  271.     blend.BlendOp = AC_SRC_OVER;
  272.     blend.BlendFlags = 0;
  273.     blend.SourceConstantAlpha = 255;
  274.     blend.AlphaFormat = AC_SRC_ALPHA;
  275.     _UpdateLayeredWindow( hWnd, NULL, NULL, &size, m_hDC, &point, 0, &blend, ULW_ALPHA );
  276.     return (frm+1)%10;
  277. }
  278.  
  279. void LayeredWnd::OnDestroy( HWND hWnd )
  280. {
  281.     KillTimer( hWnd, 1 );
  282. }
  283.  
  284. int LayeredWnd::OnNcHitTest( int xPos, int yPos )
  285. {
  286.     return HTCAPTION;
  287. }
  288.  
  289. void LayeredWnd::OnNcRButtonDown( int nHittest, POINTS pts )
  290. {
  291.     TrackPopupMenu( m_hMenu, TPM_LEFTALIGN|TPM_TOPALIGN, pts.x, pts.y, 0, m_hWnd, NULL );
  292. }
  293.